package com.ruoyi.ysVideo.controller;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.detection.domain.RiceCanopyDetectionLog;
import com.ruoyi.detection.service.RiceCanopyService;
import com.ruoyi.utils.FileTool;
import com.ruoyi.utils.MyDateUtil;
import com.ruoyi.ysVideo.domain.*;
import com.ruoyi.ysVideo.service.EzvizService;
import com.ruoyi.ysVideo.utls.MyTools;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;


/**
 * @program: class by cxf
 * @author: AbrahamBill
 * @date: 2022/9/2
 **/
@Slf4j
@RestController
@RequestMapping("/Ezviz")
public class EzvizController extends BaseController{

    @Autowired
    private EzvizService ezvizService;

    @Autowired
    private RiceCanopyService riceCanopyService;

    @Value("${ruoyi.profile}")
    private String profile;
    //开始转动
    @PostMapping("/start")
    @ApiOperation("云台开始转动，direction 方向 操作命令：0-上，1-下，2-左，3-右，4-左上，5-左下，6-右上，7-右下，8-放大，9-缩小，10-近焦距，11-远焦距\r\n" +
            "speed 速度 云台速度：0-慢，1-适中，2-快，海康设备参数不可为0\r\n")
    public String startMyRoate(String deviceSerial, int direction, int speed){
        //先通过app_key和app_secret获取token
        AppInfo info = ezvizService.selectMyAppInfo(deviceSerial);
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        //构造请求链接（请求参数+基址）
        String result = null;
        String url = "https://open.ys7.com/api/lapp/device/ptz/start";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",deviceSerial);
        param.add("channelNo",1);
        param.add("direction",direction);
        param.add("speed",speed);
        RestTemplate restTemplate = new RestTemplate();
        //请求返回参数处理
        try{
            JSONObject ret = restTemplate.postForObject(url,param,JSONObject.class);
            result = String.valueOf(ret);
            log.info(result);
        }catch (Exception e){
            log.info(e.getMessage());
        }
        return result;
    }
    //停止转动
    @PostMapping("/stop")
    public String stopMyRoate(String deviceSerial){
        AppInfo info = ezvizService.selectMyAppInfo(deviceSerial);
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        String result = null;
        String url = "https://open.ys7.com/api/lapp/device/ptz/stop";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",deviceSerial);
        param.add("channelNo",1);
        RestTemplate restTemplate = new RestTemplate();
        try{
            JSONObject ret = restTemplate.postForObject(url,param,JSONObject.class);
            result = String.valueOf(ret);
            log.info(result);
        }catch (Exception e){
            log.info(e.getMessage());
        }
        return result;
    }
    //获取直播地址
    @PostMapping("/liveaddress")
    public AjaxResult getMyLiveAddress(String deviceSerial,int quality){
        AppInfo info = ezvizService.selectMyAppInfo(deviceSerial);
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        String url = "https://open.ys7.com/api/lapp/v2/live/address/get";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",deviceSerial);
        param.add("quality",quality);
        RestTemplate restTemplate = new RestTemplate();
        MyLiveAddress res = null;
        try{
            JSONObject ret = restTemplate.postForObject(url,param,JSONObject.class);
            System.out.println(ret);
            res = JSONObject.parseObject(JSONObject.toJSONString(ret.get("data")), MyLiveAddress.class);
            res.SetAppKeyAndSecret(info);
            res.setAccessToken(myToken.getAccess_token());
            res.setExpireTime(myToken.getExpire_time());
        }catch (Exception e){
            return AjaxResult.success(e.getMessage());
        }
        return AjaxResult.success(res);
    }
    //抓拍图片
    @GetMapping("/capture")
    public AjaxResult CaptureMyImg(String deviceSerial) throws IOException {
        AppInfo info = ezvizService.selectMyAppInfo(deviceSerial);
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        String url = "https://open.ys7.com/api/lapp/device/capture";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",deviceSerial);
        param.add("channelNo",1);
        RestTemplate restTemplate = new RestTemplate();
        String pic_url = "";
        try{
            JSONObject ret = restTemplate.postForObject(url,param,JSONObject.class);
            pic_url = ret.getJSONObject("data").get("picUrl").toString();
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
        if(pic_url!=""){
            String path = profile +File.separator + "capture" + File.separator + deviceSerial;
            String date = MyDateUtil.dateFormate(new Date(), "yyyy_MM_dd_HH_mm_ss");
            String fileNme = deviceSerial + "_" + date + ".jpg";
            // 存放结果路径
            String resultPath = null;
            MyVideoImg myVideoImg = new MyVideoImg();
            boolean isSuccess = FileTool.downloadImageByUrl(pic_url, path, fileNme);
            if (isSuccess) {
                resultPath = "profile" + File.separator + "capture" + File.separator + deviceSerial + File.separator + fileNme;
                myVideoImg.setDeviceSerial(deviceSerial);
                myVideoImg.setPicUrl(resultPath);

                // 尝试抓拍图片通过水稻冠层检测，并将结果图路径放入球机抓拍表中=====
                // 构造路径
                Path path1 = Paths.get(path +"/"+fileNme);
                // 识别返回
                List<RiceCanopyDetectionLog> ret_lst = riceCanopyService.insertRiceCanopyDetectionLog(
                        new MockMultipartFile(
                                fileNme, //文件名
                                fileNme, //originalName 相当于上传文件在客户机上的文件名
                                ContentType.APPLICATION_OCTET_STREAM.toString(), //文件类型
                                Files.newInputStream(path1) //文件流
                        )
                        , myVideoImg.getDeviceSerial());
                // 判断是否有结果图路径，没有就赋值为抓拍图片路径=====
                if(ret_lst!=null){
                    if(ret_lst.size()>0){
                        myVideoImg.setResUrl(ret_lst.get(0).getResultPath().replace("_Result","__Result"));
                        myVideoImg.setTag(ret_lst.get(0).getTag());
                    }else{
                        myVideoImg.setResUrl(resultPath);
                        myVideoImg.setTag("{}");
                    }
                }else{
                    myVideoImg.setResUrl(resultPath);
                    myVideoImg.setTag("{}");
                }
                if(MyTools.isWindowsSystem()){
                    return AjaxResult.success("测试本地保存图片成功！不插入数据库", resultPath);
                }
                ezvizService.insertMyCaptureImg(myVideoImg);
            }
            return isSuccess ? AjaxResult.success("保存图片成功，保存至默认路径!", resultPath) : AjaxResult.error("保存图片出错！");
        }else{
            return AjaxResult.error("抓拍图片出错！");
        }
    }

    //删除抓拍图片记录
    @GetMapping("/deleteImageById")
    public AjaxResult deleteMyImageById(int id){
        Integer counts = ezvizService.deleteMyImgById(id);
        if(counts==0){
            return AjaxResult.success("该信息在数据库中不存在，请刷新或联系管理员");
        }
        return AjaxResult.success("删除成功，请刷新");
    }

    //展示抓拍图片列表
    @GetMapping("/captureList")
    public TableDataInfo captureMyImgList(String deviceSerial){
        startPage();
        List<ImgInfo> lst = ezvizService.selectMyCaptureImgList(deviceSerial);
        return getDataTable(lst);
    }

    //获取某个用户下的所有设备序列号(测试新增功能)
    public void getDeviceSerialByUserName(String userName){
        List<String> lst = ezvizService.selectDevicesByUserName(userName);
    }

    //根据用户获取设备信息
    @PostMapping("/getDeviceByUser")
    public AjaxResult getDevicesByUser(String userName){
        List<MyDeviceName> devices = ezvizService.selectMyDeviceNameByUser(userName);
        return AjaxResult.success(devices);
    }

    //根据设备序列号修改设备别名
    @PostMapping("/modifyDeviceName")
    public AjaxResult modifyDevieName(String deviceSerial,String newName){
        MyDeviceName device = new MyDeviceName();
        device.setDeviceSerial(deviceSerial);
        device.setRemark(newName);
        int success = ezvizService.updateRemarkName(device);
        if(success==1){
            return AjaxResult.success("修改成功！");
        }else{
            return AjaxResult.error("修改失败！");
        }
    }

    //调用预置点
    @PostMapping("/movePresetLocation")
    public AjaxResult moveMyPreSet(MyPresetInfo myPresetInfo){
        AppInfo info = ezvizService.selectMyAppInfo(myPresetInfo.getDeviceSerial());
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        String url = "https://open.ys7.com/api/lapp/device/preset/move";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",myPresetInfo.getDeviceSerial());
        param.add("channelNo",1);
        param.add("index",myPresetInfo.getIndexId());
        RestTemplate restTemplate = new RestTemplate();
        try{
            JSONObject ret = restTemplate.postForObject(url,param,JSONObject.class);
            if(ret.get("code").toString().equals("200")){
                return AjaxResult.success("成功成功预置位");
            }
            else{
                return AjaxResult.error("未知错误，请联系管理员，错误码："+ret.get("code").toString());
            }
        }catch (Exception e){
            log.info(e.getMessage());
            return AjaxResult.error(e.getMessage());
        }
    }

    // 根据设备序列号获取设备信息并更新权限表中设备状态
    @PostMapping("/getDetailInfoByDeviceSerial")
    public AjaxResult getDetailInfoByDeviceSerial(String device_serial){
        AppInfo info = ezvizService.selectMyAppInfo(device_serial);
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        String url = "https://open.ys7.com/api/lapp/device/info";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",device_serial);
        RestTemplate restTemplate = new RestTemplate();
        try{
            JSONObject data = restTemplate.postForObject(url,param,JSONObject.class);
            JSONObject ret = data.getJSONObject("data");
            if(data.get("code").toString().equals("200")){

                String isOnline = (ret.getIntValue("status")==1)?"在线":"离线";
                int update_success = ezvizService.updateDeviceStatusInfo(new MyDeviceUpdateStatus(6,device_serial,isOnline));
                if(update_success!=1){
                    return AjaxResult.error("更新设备状态失败！");
                }
                return AjaxResult.success(ret);
            }
            else{
                return AjaxResult.error("未知错误，请联系管理员，错误码："+data.get("code").toString());
            }
        }catch (Exception e){
            log.info(e.getMessage());
            return AjaxResult.error(e.getMessage());
        }
    }

    
    //添加预置点
    @PostMapping("/addPresetLocation")
    public AjaxResult addMyPreset(MyPresetInfo myPresetInfo){
        AppInfo info = ezvizService.selectMyAppInfo(myPresetInfo.getDeviceSerial());
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        String url = "https://open.ys7.com/api/lapp/device/preset/add";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",myPresetInfo.getDeviceSerial());
        param.add("channelNo",1);
        RestTemplate restTemplate = new RestTemplate();
        try{
            JSONObject ret = restTemplate.postForObject(url,param,JSONObject.class);
            System.out.println(ret);
            if(ret.get("code").toString().equals("60008")){
                return AjaxResult.error("添加的预置点个数达到上限（12个），请清除不需要的预置点后在进行添加操作");
            }else if(ret.get("code").toString().equals("200")){
                int myIndex = Integer.parseInt(ret.getJSONObject("data").get("index").toString());
                myPresetInfo.setIndexId(myIndex);
                ezvizService.insertMyPreset(myPresetInfo);
                return AjaxResult.success("添加预置位成功，编号:" + myIndex);
            }else{
                return AjaxResult.error("未知错误，请联系管理员，错误码："+ret.get("code").toString());
            }
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    //删除预置点
    @PostMapping("/clearPresetLocation")
    public AjaxResult clearMyPreset(MyPresetInfo myPresetInfo){
        AppInfo info = ezvizService.selectMyAppInfo(myPresetInfo.getDeviceSerial());
        MyToken myToken = MyTools.get_access_token(info.getAppKey(),info.getAppSecret());
        String url = "https://open.ys7.com/api/lapp/device/preset/clear";
        MultiValueMap<String,Object> param = new LinkedMultiValueMap<>();
        param.add("accessToken",myToken.getAccess_token());
        param.add("deviceSerial",myPresetInfo.getDeviceSerial());
        param.add("channelNo",1);
        param.add("index",myPresetInfo.getIndexId());
        RestTemplate restTemplate = new RestTemplate();
        try{
            JSONObject ret = restTemplate.postForObject(url,param,JSONObject.class);
            System.out.println(ret);
            System.out.println(ret.get("code").toString());
            if(ret.get("code").toString().equals("200")){
                // 删除预制点
                ezvizService.deleteMyPreset(myPresetInfo);
                // 删除预制点相关的定时任务
                ezvizService.deleteMyAutoTask(myPresetInfo);
                return AjaxResult.success("成功清除预置位");
            }
            else{
                return AjaxResult.error("未知错误，请联系管理员，错误码："+ret.getJSONObject("code").toString());
            }
        }catch (Exception e){
            log.info(e.getMessage());
            return AjaxResult.error(e.getMessage());
        }
    }

    //根据设备号查询预置位
    @PostMapping("/selectPresetBySerial")
    public AjaxResult selectMyPresetBySerial(MyPresetInfo myPresetInfo){
        List<MyPresetInfo> lst = ezvizService.selectMyPresetBySerial(myPresetInfo);
        return AjaxResult.success(lst);
    }

}